/**
 * Copyright 2000 self.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 *
 * @author Ashin Wimalajeewa
 */
package self.amigo.elem.uml;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;

import self.amigo.elem.ARectangularHandledElement;
import self.amigo.elem.SerializableEllipse;
import self.amigo.elem.SymbolPaintManagerUtils;
import self.lang.StringUtils;
import self.math.geom.EllipseUtils;
import self.math.geom.RectangleUtils;

public class InterfaceView extends LogicalClassView {
	
	/**
	 * If the internal state of this class ever changes in such a way that it can't be defaulted,
	 * then the {@link #serialVersionUID} should be incremented to ensure serialized instances cleanly fail.  
	 */
	private static final long serialVersionUID = 1;
	
  protected ARectangularHandledElement constructDelegate() {
    return new InterfaceEssential();
  }

  protected class InterfaceEssential extends Essential {
  	
	/**
	 * If the internal state of this class ever changes in such a way that it can't be defaulted,
	 * then the {@link #serialVersionUID} should be incremented to ensure serialized instances cleanly fail.  
	 */
	private static final long serialVersionUID = 1;
	
//    private Ellipse2D                   figEllipse = new Ellipse2D.Double( 10, 10, 80, 40 );
    private SerializableEllipse                   figEllipse = new SerializableEllipse( 10, 10, 80, 40 );
    private Rectangle fullRegion = new Rectangle();

    public InterfaceEssential() {
      fig.setBounds( 10, 10, 80, 40 );
      resetFrame();
    }

    protected void resetFrame() {
      figEllipse.setFrame( ((fig.width-15)/ 2) + fig.x, fig.y - 18, 15, 15);
      fullRegion.setBounds( fig.x, fig.y-15, fig.width, fig.height + 15 );
    }

    protected void paintFrame( Graphics surface ) {
      int x = (int)figEllipse.getX(), y = (int)figEllipse.getY(), w = (int)figEllipse.getWidth(), h = (int)figEllipse.getHeight();
      if ( !outlineOnly ) {
        surface.setColor( Color.white );

        String symbol = nameCompartment.aidLink;
        boolean paintSymbol = !StringUtils.isNullOrEmpty( symbol );
        if ( paintSymbol )
          SymbolPaintManagerUtils.startSymbol( surface, this, symbol );
        try {
          surface.fillOval( x, y, w, h );
          surface.setColor( frameColor );
          surface.drawOval( x, y, w, h );
        } finally {
          if ( paintSymbol )
            SymbolPaintManagerUtils.endSymbol( surface );
        }
      } else {
        surface.setColor( frameColor );
        surface.drawOval( x, y, w, h );
      }
    }

    public boolean    contains( Point within ) {
      return fullRegion.contains( within );
//      boolean ret = fig.contains( within );
//      if ( !ret )
//        ret = figEllipse.contains( within );
//      return ret;
    }

    public boolean    isWithin( Rectangle within ) {
      return fullRegion.intersects( within );
//      boolean ret = fig.intersects( within );
//      if ( !ret )
//        ret = figEllipse.intersects( within );
//      return ret;
    }

    public Rectangle  getOverallBounds() {
      Rectangle ret = super.getOverallBounds();
      ret = ret.union( fullRegion );
      return ret;
    }

    public boolean getLineIntersectionToCentre( int xFrom, int yFrom, int[] xyPoints ) {
      double[] xyP = new double[2];
      Rectangle frame = figEllipse.getBounds();
      if ( yFrom <= fig.y ) {  // use Ellipse
        EllipseUtils.getEllipseCentrePointIntersections( frame, xFrom, yFrom, xyP );
        xyPoints[0] = (int) Math.round( xyP[0] );
        xyPoints[1] = (int) Math.round( xyP[1] );
        return true;
      }
      Rectangle union = new Rectangle( frame );
      union.add( fig );
      RectangleUtils.getRectCentrePointIntersections( union, xFrom, yFrom, xyP );
      xyPoints[0] = (int)xyP[0];
      xyPoints[1] = (int)xyP[1];
      return true;
    }
  }
}
